package com.crazymaker.springcloud.base.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.crazymaker.springcloud.base.dao.SysUserDao;
import com.crazymaker.springcloud.base.entity.SysUser;
import com.crazymaker.springcloud.base.security.utils.AuthUtils;
import com.crazymaker.springcloud.common.context.SessionHolder;
import com.crazymaker.springcloud.common.dto.UserDTO;
import com.crazymaker.springcloud.common.exception.BusinessException;
import com.crazymaker.springcloud.standard.redis.RedisRepository;
import com.crazymaker.springcloud.user.info.api.dto.LoginInfoDTO;
import com.crazymaker.springcloud.user.info.api.dto.LoginOutDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.session.Session;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class SysUserServiceImpl {

    @Autowired
    private SysUserDao userDao;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RedisOperationsSessionRepository redisSessionRepository;

    @Autowired
    private RedisRepository redisRepository;

    public UserDTO getUser(Long id) {
        SysUser user = userDao.selectById(id);
        if (user != null) {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(user, userDTO);
            return userDTO;
        }
        return null;
    }

    /**
     * 登录操作
     * @param loginInfoDTO
     * @return
     */
    public LoginOutDTO login(LoginInfoDTO loginInfoDTO) {
        String username = loginInfoDTO.getUsername();

        List<SysUser> userList = userDao.selectList(new QueryWrapper<SysUser>().eq("user_name", username));
        if (userList == null || userList.size() <= 0) {
            throw BusinessException.builder().errMsg("用户不存在或者密码错误").build();
        }

        SysUser user = userList.get(0);
        String encodedPass = user.getPassword();
        String rasPass = loginInfoDTO.getPassword();
        if (passwordEncoder.matches(rasPass, encodedPass)) {
            // 登录成功
            return setSession(user);
        }
        else {
            throw BusinessException.builder().errMsg("用户不存在或者密码错误").build();
        }
    }

    public LoginOutDTO setSession(SysUser user) {
        if (user == null) {
            throw BusinessException.builder().errMsg("用户不存在或者密码错误").build();
        }

        String userId = String.valueOf(user.getUserId());
        String sessionId = redisRepository.getSessionId(userId);
        Session session = null;
        try {
            session = redisSessionRepository.findById(sessionId);
        } catch (Exception e) {
            log.info("查找现有的session 失败，将创建一个新的 session");
        }
        if (null == session) {
            session = redisSessionRepository.createSession();
            sessionId = session.getId();
            // 保存session到redis
            redisRepository.setSessionId(userId, sessionId);
        }

        String salt = user.getPassword();
        String token = AuthUtils.buildToken(sessionId, salt);

        LoginOutDTO outDTO = new LoginOutDTO();
        BeanUtils.copyProperties(user, outDTO);
        outDTO.setToken(token);
        session.setAttribute(SessionHolder.G_USER, JSON.toJSONString(outDTO));
        return outDTO;
    }


}
